/**
原生的日志记录很简单，设置一个输出文件即可
使用Uber-go zap：
快
分为 sugar 和 no sugar,区别
1.在每一微秒和每一次内存分配都很重要的上下文中，使用Logger。
它比Sugared Logger更快，内存分配次数也更少，但它只支持强类型的结构化日志记录。
2.在性能很好但不是很关键的上下文中，使用SugaredLogger。
它比其他结构化日志记录包快4-10被，并且支持结构化和printf风格的日志记录。
*/
package main

import (
	"github.com/natefinch/lumberjack"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"log"
	"os"
)

func main() {
	//goLogger()
	//zapLogger()
	zapSugarLogger()
	customLogger()
}

// customLogger 自定义日志
// 比如写入文件，格式化时间戳等
func customLogger() {
	// 需要三个配置—Encoder,WriteSyncer,LogLevel
	// encoder 编码器(如何写入日志)
	encoderConfig := zap.NewProductionEncoderConfig()
	encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder // 指定时间编码器
	encoder := zapcore.NewJSONEncoder(encoderConfig)

	// writeSyncer 指定日志将写到那里去
	// 推荐使用 lumberjack 进行日志分割
	//file, _ := os.OpenFile("./test.log", os.O_WRONLY | os.O_CREATE | os.O_APPEND, 0666)
	//zapcore.AddSync(file)

	// 使用 lumberjack 分割日志
	lumberjackLogger := &lumberjack.Logger{
		Filename:   "./test.log",
		MaxSize:    1,     // 最大的内容，单位M，默认100M
		MaxAge:     30,    // 保留的最大天数
		MaxBackups: 5,     // 保留旧文件的最大个数，默认全部保留
		Compress:   false, // 是否压缩
	}
	writerSync := zapcore.AddSync(lumberjackLogger)

	// Log Level 指定级别
	core := zapcore.NewCore(encoder, writerSync, zapcore.DebugLevel)

	// zap.AddCaller()  添加将调用函数信息记录到日志中的功能。
	logger := zap.New(core, zap.AddCaller())
	sugarLogger := logger.Sugar()

	for i := 0; i < 10000; i++ {
		sugarLogger.Info("this is info message")
		sugarLogger.Infof("this is %s, %d", "aaa", 1234)
		sugarLogger.Error("this is error message")
		sugarLogger.Info("this is info message")
	}

}

// zapLogger 使用zap的日志
func zapLogger() {
	//zapLog := zap.NewExample()
	zapLog, _ := zap.NewProduction()
	zapLog.Debug("this is debug message")
	zapLog.Info("this is info message")
	zapLog.Info("this is info message with fileds",
		zap.Int("age", 24), zap.String("agender", "man"))
	zapLog.Warn("this is warn message")
	zapLog.Error("this is error message")
}

// zapSugarLogger 主要区别是多调用一个sugar
func zapSugarLogger() {
	zapLog, _ := zap.NewProduction()
	sugarLog := zapLog.Sugar()
	sugarLog.Debug("this is debug message")
	sugarLog.Info("this is info message")
	sugarLog.Info("this is info message with fileds",
		zap.Int("age", 24), zap.String("agender", "man"))
	sugarLog.Warn("this is warn message")
	sugarLog.Error("this is error message")
}

func goLogger() {
	setupLogging()
	log.Println("something error")
}

// 原生的日志，只要设置输出文件即可
func setupLogging() {
	// 设置一个输出的文件
	logFileLocation, err := os.OpenFile("./test.log", os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0666)
	if err != nil {
		log.Println(err)
	}
	log.SetOutput(logFileLocation)
}
